package suncertify.service.remote;

import suncertify.db.RecordNotFoundException;
import suncertify.db.DuplicateKeyException;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * Remote data interface for accessing database through RMI
 */
public interface RemoteData extends Remote {

    /**
     * name of remote object for rmi binding
     */
    String REMOTE_NAME = "RemoteData";

    /**
     * read data from database
     * @param recNo id of record
     * @return data
     * @throws RemoteException if remote error occurred
     * @throws RecordNotFoundException if record not found
     */
    String[] read(int recNo) throws RemoteException, RecordNotFoundException;

    /**
     * updates record data
     * @param recNo id of record
     * @param data data to store
     * @param lockCookie lock cookie
     * @throws RemoteException if remote error occurred
     * @throws RecordNotFoundException if record not found
     */
    void update(int recNo, String[] data, long lockCookie) throws RemoteException, RecordNotFoundException;

    /**
     * deletes record
     * @param recNo record id
     * @param lockCookie lock cookie
     * @throws RemoteException if remote error occurred
     * @throws RecordNotFoundException if record not found
     */
    void delete(int recNo, long lockCookie) throws RemoteException, RecordNotFoundException;

    /**
     * finds matched records
     * @param criteria search criteria
     * @return ids of founded records
     * @throws RemoteException if remote error occurred
     */
    int[] find(String[] criteria) throws RemoteException;

    /**
     * creates new record in database
     * @param data data to store
     * @return id of new record
     * @throws RemoteException if remote error occurred
     * @throws DuplicateKeyException if record with this primary key already exists (for future)
     */
    int create(String[] data) throws RemoteException, DuplicateKeyException;

    /**
     * locks the record
     * @param recNo record id
     * @param remoteId remote client id for managing session
     * @return lock cookie, if successfull, lock cookie > 0, else -1
     * @throws RemoteException if remote error occurred
     * @throws RecordNotFoundException if record not found
     */
    long lock(int recNo, long remoteId) throws RemoteException, RecordNotFoundException;

    /**
     * unlocks the record
     * @param recNo record id
     * @param cookie lock cookie
     * @throws RemoteException if remote error occurred
     * @throws RecordNotFoundException if record not found
     */
    void unlock(int recNo, long cookie) throws RemoteException, RecordNotFoundException;

    /**
     * returns the column name
     * @param col index of column
     * @return column name
     * @throws RemoteException if revote error occurred
     */
    String getColumnName(int col) throws RemoteException;

    /**
     * returns column count
     * @return column count
     * @throws RemoteException if revote error occurred
     */
    int getColumnCount() throws RemoteException;

    /**
     * cancels lock by interrupting waiting thread
     * @param id record id
     * @param clientId remote client id
     * @throws RemoteException if revote error occurred
     */
    void cancelLocking(Integer id, Long clientId) throws RemoteException;

    /**
     * creates and returns a new unique id for remote client
     * @return id
     * @throws RemoteException if revote error occurred
     */
    long getRemoteClientId() throws RemoteException;

    /**
     * creates remote session for client
     * @param clientId remote client id
     * @throws RemoteException if revote error occurred
     */
    void startSession(long clientId) throws RemoteException;

    /**
     * closes remote session for client and terminating all waiting threads
     * @param clientId remote client id
     * @throws RemoteException if revote error occurred
     */
    void closeSession(long clientId) throws RemoteException;
}
